package com.wjm.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * Data:2022年08月06日
 * Author:wjm
 * Content:
 *
 *
 *  HttpRequest  表示请求对象
 *  在这个类上我们将请求的相关信息设计为属性来分别保存，并在构造方法中完成解析请求的工作
 *
 *  因为RequestHandle只需要做业务逻辑的控制，而具体的请求拆分我们需要单独封装到HttpRequest类中完成
 *  后期需要那一部分的内容，直接调用即可，实现了功能的扩展
 *
 */
public class HttpRequest {
    Socket socket;
    /*
    * 请求行
    * */
    private String method;   //请求方式
    private String url;      //抽象路径
    private String protocol; //版本信息

    /*
    * 消息头
    * */
    Map<String,String> map = new HashMap<>();

    /*
    * 消息正文
    * TODO
    * */


    //构造方法
    public HttpRequest(Socket socket){
        this.socket = socket;
        //读取并拆分请求行
        parseRequestLine();
        //读取并拆分消息头
        parseHeaders();
    }


    /**
     *  读取一行字符串
     * @return 返回读取的一行字符串
     */
    private String readLine() {

        try{
            //获取输入流
            InputStream in = socket.getInputStream();
            //解析socket请求信息
            int a;
            //声明一个空字符串用,来装读到的字符
            StringBuilder stringBuilder = new StringBuilder();
            //申明两个变量用来表示当前读到的字符，和上一次读到的字符
            char cur = ' ';//当前的字符
            char pre = ' ';//上一个字符
            while ((a=in.read()) != -1){
                cur = (char)a;
                //判断是否读到一行的末尾,因为请求的每一行是以换行符和回车符为结尾的
                if (cur == 10 && pre == 13){
                    break;
                }
                //将当前的字符装到空字符串中
                stringBuilder.append(cur);
                //将当前字符赋值给上一个字符
                pre = cur;
            }
            //将stringBuilder转换为String类型，并去掉回车符CR
            return stringBuilder.toString().trim();


        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 读取并拆分请求行
     */
    public void parseRequestLine(){
        //读取第一行字符串，也就是请求行
        String line = readLine();

        //TODO 通过空格拆分请求行,找出请求资源路径
        String[] data = line.split("\\s");
        //请求方式
        method = data[0];
        //抽象路径
        url = data[1];
        //版本信息
        protocol = data[2];
        System.out.println(line);
        System.out.println("请求方式："+method);
        System.out.println("抽象路径："+url);
        System.out.println("版本信息："+protocol);
    }


    /**
     * 读取并拆分消息头
     */
    public void parseHeaders(){
        /*
         * TODO 读取和拆分消息头
         *   key : value [CRLF]
         *   [CRLF]
         * */
        while (true){
            String str = readLine();
            //判断是否读到消息头的末尾
            if (str.isEmpty()){//因为消息头部分结束的标志是单独的在向服务器发送一个连续的标识符【回车符和换行符 CRLF】。
                break;
            }
            System.out.println("消息头内容是："+str);
            //通过:冒号拆分读到的一行
            String[] data1 = str.split(":");
            //将读到的内容以键值对方式存入集合,消息头名称作为key，消息头名称的内容作为value
            map.put(data1[0],data1[1]);

        }
        //输出map集合
        System.out.println(map);
    }


}
